<template>
  <div class="catalog_span">
    <div class="catalog_span_left">
      <el-scrollbar>
        <el-tree
          :data="catalogList"
          :props="catalogTree"
          :expand-on-click-node="false"
          :default-expand-all="true"
          :highlight-current="true"
          @node-click="selectCatalog"
        >
          <template #default="{ node, data }">
            <span class="tree_node_container">
              <span class="tree_node_label">{{ node.label }}</span>
              <span>
                <el-button
                  size="small"
                  type="primary"
                  text
                  @click="addCatalogDialog(data, $event)"
                  :disabled="!btOption.btCreateCatalog"
                  >新增</el-button
                >
                <el-button
                  v-if="!data.isRoot"
                  size="small"
                  type="danger"
                  text
                  @click="removeCatalog(node, data, $event)"
                  :disabled="showDeleteButton(data)"
                  >删除</el-button
                >
              </span>
            </span>
          </template>
        </el-tree>
      </el-scrollbar>
    </div>
    <div class="catalog_span_right">
      <table-span
        :current-page="fileTableData.current"
        :page-size="fileTableData.size"
        :total="fileTableData.total"
        :isShowTool="false"
        :page-layout="fileTableData.pageLayout"
        :size-change="handleSizeChange" 
        :current-change="handleCurrentChange">
        <template v-slot:searchItem>
          <div class="search_item_span">
            <el-input v-model="fileSearchCondition.origFileName"
            placeholder="请输入文件名称" clearable></el-input>
          </div>
          <div class="search_item_span">
            <el-button icon="Search" size="default" type="primary" @click="searchFileData">查询</el-button>
          </div>
          <div class="search_item_span">
            <el-button icon="Plus" size="default" type="primary" @click="openFileUploadDialog">上传文件</el-button>
          </div>
        </template>
        <template v-slot:searchTable>
          <el-scrollbar height="100%">
            <div class="file_show_container">
              <el-card class="file_span" shadow="hover" v-for="item in fileTableData.records" :key="item.fileId">
                <div style="position:relative;height: 10px;margin-left: 80px; margin-top: 0px; margin-top: -10px;" v-show="item.shareType == 1">
                  <el-tag
                    size="small"
                    type="success"
                    effect="dark"
                    round
                  >
                    已分享
                  </el-tag>
                </div>
                <div class="icon_file_span">
                  <i :class="item.icon"></i>
                </div>
                <div class="file_text_span">
                  <el-tooltip
                    class="box-item"
                    effect="light"
                    :content="item.origFileName"
                    placement="bottom"
                    trigger="click"
                  >
                  {{item.origFileName}}
                  </el-tooltip>
                </div>
                <div class="file_operate_span">
                  <div @click="downloadFile(item)">
                    <i class="fas fa-download" style="color: #409EFF"></i>
                  </div>
                  <div @click="shareFile(item)">
                    <i class="fas fa-share-nodes" style="color: #409EFF"></i>
                  </div>
                  <div @click="deleteFile(item)">
                    <i class="fas fa-trash-can" style="color: #f89898"></i>
                  </div>
                </div>
              </el-card>
            </div>
          </el-scrollbar>
        </template>
      </table-span>
    </div>
    <el-dialog
      v-model="catalogDialogOption.show"
      :title="catalogDialogOption.title"
      width="450px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="catalogDialogBeforeClose"
      @close="catalogDialogClose"
    >
      <el-form
        ref="catalogFormRef"
        :model="catalogForm"
        :rules="catalogFormRules"
        label-width="80px"
        status-icon
      >
        <el-form-item label="父级目录">
          <el-input
            v-model="catalogForm.parentCatalog" disabled></el-input>
        </el-form-item>
        <el-form-item label="目录名称" prop="catalogName">
          <el-input
            v-model="catalogForm.catalogName"
            placeholder="请填目录名称"
            :clearable="true"
          ></el-input>
        </el-form-item>
        <el-form-item label="目录描述">
          <el-input
            v-model="catalogForm.catalogDescription"
            placeholder="请填写目录描述"
            :clearable="true"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="catalogDialogBeforeClose">取消</el-button>
          <el-button type="primary" @click="saveCatalog">保存</el-button>
        </span>
      </template>
    </el-dialog>
    <el-dialog
      v-model="fileUploadDialogOption.show"
      title="上传文件"
      width="360px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="fileUploadDialogBeforeClose"
      @close="fileUploadDialogClose"
    >
      <el-upload
      v-model:file-list="fileUploadList"
      class="upload-demo"
      multiple
      :auto-upload="false"
      >
        <el-button type="primary">选择文件</el-button>
      </el-upload>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="fileUploadDialogBeforeClose">取消</el-button>
          <el-button type="primary" @click="fileUpload">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!--  设置文件的分享  -->
    <el-dialog
      v-model="fileShareDialogOption.show"
      title="文件分享设置"
      width="360px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="fileShareDialogBeforeClose"
      @close="fileShareDialogClose"
    >
      <el-form
        ref="shareFormRef"
        :model="shareForm"
        :rules="shareFormRules"
        label-width="80px"
        status-icon
      >
        <el-form-item label="分享类型">
          <el-select v-model="shareForm.shareType"  placeholder="请选择分享类型" style="width:220px" @change="shareTypeChange">
            <el-option
              v-for="item in shareType"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="有效期限" prop="expireType" v-if="shareForm.shareType == 1">
          <el-select v-model="shareForm.expireType"  placeholder="请选择有效期限" style="width:220px" @change="expireTypeChange">
            <el-option
              v-for="item in expireType"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="有效期限" prop="expireDate" v-if="shareForm.shareType == 1 && shareForm.expireType == 0">
          <el-date-picker
            v-model="shareForm.expireDate"
            type="datetime"
            value-format="YYYY-MM-DD HH:mm:ss"
            placeholder="请选择日期时间"
          />
        </el-form-item>
        <el-form-item label="分享地址" v-if="shareForm.shareType == 1">
          <el-input v-model="shareForm.shareUrl" style="width:220px" readonly>
              <template #append>
                  <el-link :underline="false" @click="copyUrl">复制</el-link>
              </template>
          </el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="fileShareDialogBeforeClose">取消</el-button>
          <el-button type="primary" @click="saveFileShare">保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { ElMessage } from "element-plus";
import TableSpan from "@/components/table-span.vue";
import { tool } from "@/js/tool.js";
import { config } from "@/js/config.js";

export default {
  name: "catalog",
  data: function () {
    return {
      btOption: {
        btCreateCatalog: null,
        btDeleteCatalog: null
      },
      catalogList: null,
      catalogTree: {
        children: "children",
        label: "catalogName",
      },
      catalogDialogOption: {
        title: "",
        show: false,
      },
      catalogForm: {
        parentCatalog: "",
        catalogName: "",
        catalogDescription: ""
      },
      catalogFormRules: {
        catalogName: [
            { required: true, message: '请填写目录名称', trigger: 'blur' }
        ]
      },
      fileTableData: {
        pageLayout: "total, sizes, prev, pager, next",
        total: 0,
        size: 50,
        current: 1,
        records: [],
        selectRoleRow: null
      },
      fileSearchCondition: {
        origFileName: "",
        catalogId: null,
        page: 1,
        size: 50
      },
      curSelectCatalog: null,
      fileUploadDialogOption: {
        show: false
      },
      fileUploadList: [],
      shareType: [
        {'value': 0, 'label': '未分享'},
        {'value': 1, 'label': '已分享'}
      ],
      expireType: [
        {'value': 0, 'label': '指定日期'},
        {'value': 1, 'label': '长期有效'}
      ],
      fileShareDialogOption: {
        show: false
      },
      shareForm: {
        fileId: null,
        shareType: null,
        expireType: null,
        expireDate: null,
        shareUrl: null
      },
      shareFormRules: {
        expireType: [
          { required: true, message: '请选择到期类型', trigger: 'blur' }
        ],
        expireDate: [
          { required: true, message: '请选择到期时间', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    addCatalogDialog: function (data, event) {
      this.catalogDialogOption.title = "新增文件目录";
      this.catalogDialogOption.show = true;

      this.catalogForm.parentCatalog = data.catalogPath;
      event.stopPropagation();
    },
    removeCatalog: function (node, data, event) {
      let confirmMessage = "是否删除目录:"+ data.catalogName +"？";
      const obj = this;
      this.$confirm(confirmMessage).then(function () {
        const param = {
          catalogId: data.catalogId
        }
        deleteCatalog(obj, param);
      }).catch(function () {});
      event.stopPropagation();
    },
    showDeleteButton: function (data) {
      if(!this.btOption.btDeleteCatalog){
        return true;
      }
      if(data.children != null && data.children.length > 0){
        return true;
      }
      return false;
    },  
    catalogDialogBeforeClose: function () {
      catalogDialogCloseTips(this);
    },
    catalogDialogClose: function () {
        this.catalogForm = {
            parentCatalog: "",
            catalogName: "",
            catalogDescription: ""
        }
        this.$refs["catalogFormRef"].clearValidate();
    },
    saveCatalog: function () {
        const obj = this;
        this.$refs["catalogFormRef"].validate(function(valid) {
            if(valid){
                createCatalog(obj);
            }else{
                return false;
            }
        });
    },
    selectCatalog: function(data, node, treeNode, event){
      if(data.catalogPath == "/"){
        return;
      }
      this.fileSearchCondition.catalogId = data.catalogId;
      this.curSelectCatalog = data;
      this.fileSearchCondition.page = 1;
      getCatalogFileList(this);
    },
    handleCurrentChange: function(val){
      this.fileSearchCondition.page = val;
      getCatalogFileList(this);
    },
    handleSizeChange: function(val){
      this.fileSearchCondition.page = 1;
      this.fileSearchCondition.size = val;
      getCatalogFileList(this);
    },
    searchFileData: function(){
      if(this.fileSearchCondition.catalogId == null){
        ElMessage({
          showClose: true,
          message: '请选择文件夹',
          type: "error",
        });
        return;
      }
      getCatalogFileList(this);
    },
    openFileUploadDialog: function(){
      if(this.fileSearchCondition.catalogId == null){
        ElMessage({
            showClose: true,
            message: "请先选择上传的目录",
            type: "error",
        });
        return;
      }
      this.fileUploadDialogOption.show = true;
    },
    fileUploadDialogBeforeClose: function(){
      fileUploadDialogCloseTips(this);
    },
    fileUploadDialogClose: function(){
      this.fileUploadList = [];
    },
    fileUpload: function(){
      if(this.fileUploadList == null || this.fileUploadList.length == 0){
        ElMessage({
          showClose: true,
          message: '请先选择上传的文件',
          type: "error",
        });
        return;
      }

      let paramForm = new FormData();
      const fileList = new Array();
      for(let i=0;i<this.fileUploadList.length;i++){
        paramForm.append("files", this.fileUploadList[i].raw)
      }
      paramForm.append("catalogPath", this.curSelectCatalog.catalogPath);
      
      saveUploadFile(this, paramForm);
    },
    downloadFile: function(file){
      const param = {
        fileName: file.fileName
      }
      downloadFile(this, param);
    },
    shareFile: function(file){
      this.shareForm.fileId = file.fileId;
      this.shareForm.shareType = file.shareType;
      this.shareForm.expireType = file.expireType;
      this.shareForm.expireDate = file.expireDate;
      if(file.shareUrl){
        this.shareForm.shareUrl = config.requestConfig.httpDomain + file.shareUrl;
      }
      this.fileShareDialogOption.show = true;
    },
    deleteFile: function(file){
      const obj = this;
      const confirmMessage = "是否删除当前文件？";
        this.$confirm(confirmMessage).then(function(){
          const param = {
            fileId : file.fileId
          };
          deleteUploadFile(obj, param);
        }).catch(function(){});
    },
    fileShareDialogBeforeClose: function(){
      fileShareDialogCloseTips(this);
    },
    fileShareDialogClose: function(){
      this.shareForm.shareType = null;
      this.shareForm.expireType = null;
      this.shareForm.expireDate = null;
      this.shareForm.shareUrl = null;
      this.$refs["shareFormRef"].clearValidate();
    },
    saveFileShare: function(){
      const obj = this;
      this.$refs["shareFormRef"].validate(function(valid) {
        if(valid){
          saveShareFile(obj);
        }else{
          return false;
        }
      });
    },
    shareTypeChange: function(val){
      if(val == 0){
        this.shareForm.expireType = null;
        this.shareForm.expireDate = null;
      }
    },
    expireTypeChange: function(val){
      this.shareForm.expireDate = null;
    },
    copyUrl: function(){
      navigator.clipboard.writeText(this.shareForm.shareUrl)
      .then(() => {
        ElMessage({
          showClose: true,
          message: '复制成功',
          type: 'success'
        });
      })
      .catch(() => {
        ElMessage({
          showClose: true,
          message: '复制失败',
          type: 'error'
        });
      });
    }
  },
  created: function () {
    const menuId = [this.$route.query.menuId];
    const obj = this;
    new tool.getAuthorisedRequest(menuId, this.btOption, function () {
      getCatalogList(obj);
    });
  },
  components: {
    TableSpan,
  },
};

/**
 * 获取文件目录列表
 * @param app
 */
function getCatalogList(app) {
  const url = "/basic/catalog/getCatalogList";
  tool.formJsonRequest(url, {}, null, function (data) {
    if (data.code === "0000") {
      const rootCatalog = {
        catalogName: "根目录",
        catalogPath: "/",
        children: data.data,
        isRoot: true
      }
      app.catalogList = [rootCatalog];
    } else {
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 获取文件目录列表
 * @param app
 */
function createCatalog(app) {
  const url = "/basic/catalog/createCatalog";
  const param = {
    catalogName: app.catalogForm.parentCatalog + "/" + app.catalogForm.catalogName,
    catalogDescription: app.catalogForm.catalogDescription,
    authType: 0
  }
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
        app.catalogDialogOption.show = false;
        getCatalogList(app);
    } else {
        ElMessage({
            showClose: true,
            message: data.message,
            type: "error",
        });
    }
  });
}

/**
 * 删除文件目录
 * @param app
 * @param param 文件信息
 */
function deleteCatalog(app, param) {
  const url = "/basic/catalog/deleteCatalog";
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
      getCatalogList(app);
      ElMessage({
        showClose: true,
        message: "删除目录成功",
        type: "success"
      });
    } else {
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 上传文件
 * @param app
 * @param param 文件信息
 */
function saveUploadFile(app, param) {
  const url = "/basic/catalog/uploadFile";
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
      getCatalogList(app);
      ElMessage({
        showClose: true,
        message: "上传成功",
        type: "success"
      });
      app.fileUploadDialogOption.show = false;
      getCatalogFileList(app);
    } else {
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 获取文件列表
 * @param app
 */
function getCatalogFileList(app) {
  const url = "/basic/catalog/getCatalogFileList";
  const param = app.fileSearchCondition;
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
      const result = data.data;
      app.fileTableData.total = result.total;
      app.fileTableData.size = result.size;
      app.fileTableData.current = result.current;
      app.fileTableData.records = result.records;
      const defaultFileIcon = "far fa-file";
      for(let i = 0; i < app.fileTableData.records.length; i ++){
        let item = app.fileTableData.records[i];
        let showIcon = defaultFileIcon;
        if(item.fileType){
          let tempIcon = tool.fileTypeToIcon[item.fileType];
          if(tempIcon){
            showIcon = tempIcon;
          }
        }
        item["icon"] = showIcon;
      }
    } else {
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 删除已经上传的文件
 * @param app
 * @param param 文件信息
 */
function deleteUploadFile(app, param) {
  const url = "/basic/catalog/deleteFile";
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
      ElMessage({
        showClose: true,
        message: "文件删除成功",
        type: "success"
      });
      getCatalogFileList(app);
    } else {
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 下载上传的文件
 * @param app
 * @param param 文件信息
 */
function downloadFile(app, param) {
  const url = "/basic/catalog/downloadFile";
  new tool.formJsonRequestStream(url, param, null, function (data) {
    let fileName = data.headers["content-disposition"].replace("attachment;filename=","");
    let file = new Blob([data.data]);
    let url = URL.createObjectURL(file);
    const aLink = document.createElement("a");
    aLink.href = url;
    aLink.setAttribute("download", decodeURI(fileName));
    document.body.appendChild(aLink);
    aLink.click();
    document.body.removeChild(aLink);
  });
}

/**
 * 保存分享信息
 * @param app
 * @param param 分享信息
 */
function saveShareFile(app){
  const url = "/basic/catalog/setShareFile";
  const param = app.shareForm;
  tool.formJsonRequest(url, param, null, function (data) {
    if (data.code === "0000") {
      app.fileShareDialogOption.show = false;
      getCatalogFileList(app);
    }else{
      ElMessage({
        showClose: true,
        message: data.message,
        type: "error",
      });
    }
  });
}

/**
 * 添加目录弹窗关闭时的提示信息
 * @param app
 */
function catalogDialogCloseTips(app) {
    let confirmMessage = "是否放弃新增目录？";
    app.$confirm(confirmMessage).then(function () {
      app.catalogDialogOption.show = false;
    }).catch(function () {});
}

/**
 * 上传文件弹窗关闭时的提示信息
 * @param app
 */
function fileUploadDialogCloseTips(app) {
    let confirmMessage = "是否放弃上传文件？";
    app.$confirm(confirmMessage).then(function () {
      app.fileUploadDialogOption.show = false;
    }).catch(function () {});
}

/**
 * 文件分享设置弹窗关闭时的提示信息
 * @param app
 */
 function fileShareDialogCloseTips(app) {
    let confirmMessage = "是否放弃修改的信息？";
    app.$confirm(confirmMessage).then(function () {
      app.fileShareDialogOption.show = false;
    }).catch(function () {});
}
</script>
<style>
.catalog_span {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  font-family: Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB,
    "\5B8B\4F53", sans-serif;
  flex-wrap: wrap;
  overflow-x: auto;
}
.catalog_span .catalog_span_left {
  width: 320px;
  height: 100%;
  border-right: 1px solid #ebeef5;
}
.catalog_span .catalog_span_right {
  width: calc(100% - 340px);
  height: 100%;
  border-left: 1px solid #ebeef5;
}
.catalog_span_left .el-tree {
  min-width: calc(100% - 8px);
  display: inline-block !important;
  padding-right: 8px;
}
.catalog_span_left .el-tree-node__label {
  display: block;
  width: 100%;
}
.tree_node_container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  justify-content: space-between;
}
.tree_node_label {
  line-height: 24px;
}
.search_item_span{
  min-width: 80px;
  height: auto;
  margin-top: 5px;
  margin-left: 10px;
}
.file_show_container{
  width: calc(100% - 8px);
  height: auto;
  margin-left: 0px;
  margin-top: 0px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.file_span {
  width: 160px;
  height: auto;
  margin-left: 10px;
  margin-right: 10px;
  margin-top: 10px;
  overflow: hidden;
  color: #666666;
}
.file_span .icon_file_span {
  width: calc(100% - 8px);
  height: 80px;
  margin-right: auto;
  margin-left: auto;
  text-align: center;
  font-size: 70px;
  font-weight: 100;
  line-height: 80px;
}
.file_span .file_text_span{
  width: 100%;
  height: 18px;
  line-height: 18px;
  margin-top: 10px;
  overflow: hidden;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  cursor: default;
}
.file_span .file_operate_span{
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 18px;
  margin-top: 10px;
  font-size: 18px;
  line-height: 18px;
  justify-content: flex-end;
}
.file_operate_span div{
  margin-right: 10px;
  cursor: pointer;
}
</style>